package org.jiamandan.com.controller;

import cn.hutool.core.date.DateUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.jiamandan.com.cache.CacheNames;
import org.jiamandan.com.config.TcpInboundAdapter;
import org.jiamandan.com.config.UdpServerHandler;
import org.jiamandan.com.constant.DXConstant;
import org.jiamandan.com.dto.DXBasicDto;
import org.jiamandan.com.service.IRechargePileService;
import org.jiamandan.com.utils.CommonUtil;
import org.jiamandan.com.utils.IdentityIdUtil;
import org.jiamandan.com.utils.RedisUtil;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;

@RestController
@AllArgsConstructor
@RequestMapping("/charge-test")
@Slf4j
public class ChargeTestController {

    private IRechargePileService iRechargePileService;
    private RedisUtil redisUtil;

    /**
     * jmd-2口下发测试通电
     * @param pileNo  设备编号
     * @param gunNo   充电枪号
     * @param isOpen  0停止充电  1开启充电
     * @return
     */
    @GetMapping("/testJsy2charge")
    public String testJsy2charge(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        iRechargePileService.testJsy2charge(pileNo,gunNo,isOpen);
        return "下发成功";
    }

    /**
     * jmd-下发修改时间
     * @param pileNo  设备编号
     * @param gunNo   充电枪号
     * @return
     */
    @GetMapping("/testJsy2Time")
    public String testJsy2Time(@RequestParam String pileNo,@RequestParam String gunNo){
        iRechargePileService.testJsy2Time(pileNo,gunNo);
        return "下发成功";
    }

    /**
     * jmd-4/10下发通电测试
     * @param pileNo  设备编号
     * @param gunNo   充电枪号
     * @param isOpen  0停止充电  1开启充电
     * @return
     */
    @GetMapping("/testJsy10charge")
    public String testJsy10charge(@RequestParam String pileNo,@RequestParam String gunNo,@RequestParam Integer isOpen){
        try {
            iRechargePileService.testJsy10charge(pileNo,gunNo,isOpen);
        }catch (Exception e){
            return e.getMessage();
        }
        return "下发成功";
    }

    /**
     * 检测是否在线
     * @param pileNo  设备编号
     * @return
     */
    @GetMapping("/testJsy10online")
    public String testJsy10online(@RequestParam String pileNo){
        return iRechargePileService.testJsy10online(pileNo);
    }



    /**
     * 下发通电测试
     */
    @GetMapping("/testDX10charge")
    public String testDX10charge(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        Channel channel = getChannel(pileNo);
        long id = IdentityIdUtil.getFlowIdInstance().nextId();
        String time1 = DateFormatUtils.format(new Date(), "MMddHHmmss");
        Long format = Long.valueOf(time1);
        String orderNo = Long.toHexString(format);
        String modeType = "00"; //计费方式
        Integer maxChargeTime = 36000;
        StringBuilder response = new StringBuilder();
                    response.append(StringUtils.leftPad(orderNo,8, "0"))   //订单编号 8位数
                            .append(StringUtils.leftPad(String.valueOf(id),32, "0"))
                            .append(gunNo)
                            .append(modeType)   //计时
                            .append(CommonUtil.reverseHex(StringUtils.leftPad(Integer.toHexString(maxChargeTime), 8, "0"))) //充电时长
                            .append("2000")   //单位为 mA，限制的最大充电电流，为 0 表示不限制
                            .append("01")   //播报账户余额
                            .append("00000300")   //账户剩余金额【用于语音播报】
                            .append("00000300");   //本次扣费金额【于语音播报或者显示播】
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("00");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage(response.toString(),dto,gunNo, DXConstant.Cmd.CMD_A04);
        return "下发成功";
    }

    /**
     * 下发停止充电
     * @param
     */
    @GetMapping("/testDX10StopCharge")
    public String testDX10StopCharge(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        StringBuilder response = new StringBuilder();
                            response.append(gunNo);
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage(response.toString(),dto,gunNo, DXConstant.Cmd.CMD_A02);
        return "下发成功";
    }

    /**
     *
     * @param pileNo
     * @param gunNo
     * @param isOpen
     * @return
     */
    @GetMapping("/setStreamToPileInfo")
    public String setStreamToPileInfo(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        DXBasicDto dto = new DXBasicDto();

        StringBuilder response = new StringBuilder();
            response.append("0100") //单位为毫安，充满自停判断的电流值，为 0 表示不启用该功能
                    .append("3600")       //充满自停判断时间
                    .append("0000")       //拔出自停门槛电流值
                    .append("0060")       //拔出自停判断时间
                    .append("0600")       //充满自停后续充时间
                    .append("0000");
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage(response.toString(),dto,gunNo, DXConstant.Cmd.CMD_089);
        return "下发成功";
    }


    @GetMapping("/testStreamToPileInfo")
    public String testStreamToPileInfo(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage("",dto,gunNo, DXConstant.Cmd.CMD_009);
        return "下发成功";
    }

    @GetMapping("/testGetIpPort")
    public String testGetIpPort(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage("",dto,gunNo, DXConstant.Cmd.CMD_004);
        return "下发成功";
    }

    /**
     * 读取BS参数
     * @param pileNo
     * @param gunNo
     * @param isOpen
     * @return
     */
    @GetMapping("/testGetBs")
    public String testGetBs(@RequestParam String pileNo, @RequestParam String gunNo, @RequestParam Integer isOpen){
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(pileNo);
        UdpServerHandler.sendMessage("",dto,gunNo, DXConstant.Cmd.CMD_008);
        return "下发成功";
    }


   private Channel getChannel(String pileNo) {
        Map<String, ChannelId> channels = (Map<String, ChannelId>) redisUtil.get(CacheNames.TCP_CHANNEL);
        if (channels == null || channels.get(pileNo) == null) {
            log.error(pileNo + ":未找到相关发送通道ID");
            return null;
        }
        log.info("==========" + channels.get(pileNo) + "------" + pileNo + "=============");
        Channel channel = TcpInboundAdapter.clients.find(channels.get(pileNo));
        if (channel == null) {
            log.error(pileNo + ":未找到相关发送通道");
            return null;
        }
        log.error("设备号:" + pileNo + "channel:" + channel.id() + "是否active:" + channel.isActive());
        return channel;
    }

}
